﻿using RS.Echarts.Models.XAxis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RS.Echarts.Models
{
    /// <summary>
    /// 极坐标系的半径轴，用于定义极坐标系中半径相关的属性和行为。
    /// </summary>
    public class RadiusAxis
    {
        /// <summary>
        /// 组件ID。默认不指定。指定则可用于在option或者API中引用组件。
        /// </summary>
        public string? Id { get; set; }

        /// <summary>
        /// 是否显示半径轴。
        /// </summary>
        public bool Show { get; set; }

        /// <summary>
        /// 半径轴所在的极坐标系的索引，默认位于第一个极坐标系。
        /// </summary>
        public int PolarIndex { get; set; }

        /// <summary>
        /// 从v5.3.0开始支持，在多个半径轴为数值轴的时候，可以开启该配置项自动对齐刻度。只对'value'和'log'类型的轴有效。
        /// </summary>
        public bool AlignTicks { get; set; }

        /// <summary>
        /// 半径轴的类型。可选'value'（数值轴，适用于连续数据）、'category'（类目轴，适用于离散的类目数据，为该类型时类目数据可自动从series.data或dataset.source中取，或者可通过radiusAxis.data设置类目数据）、'time'（时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，星期，日还是小时范围的刻度）、'log'（对数轴，适用于对数数据，对数轴下的堆积柱状图或堆积折线图可能带来很大的视觉误差，并且在一定情况下可能存在非预期效果，应避免使用）。
        /// </summary>
        public string? Type { get; set; }

        /// <summary>
        /// 坐标轴名称。
        /// </summary>
        public string? Name { get; set; }

        /// <summary>
        /// 坐标轴名称显示位置。可选'start'、'middle'或者'center'、'end'。
        /// </summary>
        public string? NameLocation { get; set; }

        /// <summary>
        /// 坐标轴名称的文字样式。
        /// </summary>
        public TextStyle NameTextStyle { get; set; }

        /// <summary>
        /// 坐标轴名称与轴线之间的距离。
        /// </summary>
        public int NameGap { get; set; }

        /// <summary>
        /// 坐标轴名字旋转，角度值。
        /// </summary>
        public int NameRotate { get; set; }

        /// <summary>
        /// 坐标轴名字的截断。
        /// </summary>
        public NameTruncate NameTruncate { get; set; }

        /// <summary>
        /// 是否是反向坐标轴。
        /// </summary>
        public bool Inverse { get; set; }

        /// <summary>
        /// 坐标轴两边留白策略，类目轴和非类目轴的设置和表现不一样。
        /// 类目轴中boundaryGap可以配置为true和false。默认为true，这时候刻度只是作为分隔线，标签和数据点都会在两个刻度之间的带(band)中间。
        /// 非类目轴，包括时间，数值，对数轴，boundaryGap是一个两个值的数组，分别表示数据最小值和最大值的延伸范围，可以直接设置数值或者相对的百分比，在设置min和max后无效。示例：boundaryGap: ['20%', '20%']。
        /// </summary>
        public object? BoundaryGap { get; set; }

        /// <summary>
        /// 坐标轴刻度最小值。可以设置成特殊值'dataMin'，此时取数据在该轴上的最小值作为最小刻度。不设置时会自动计算最小值保证坐标轴刻度的均匀分布。
        /// 在类目轴中，也可以设置为类目的序数（如类目轴data: ['类A', '类B', '类C']中，序数2表示'类C'。也可以设置为负数，如 -3）。
        /// 当设置成function形式时，可以根据计算得出的数据最大最小值设定坐标轴的最小值。如：min: function (value) { return value.min - 20; }，其中value是一个包含min和max的对象，分别表示数据的最大最小值，这个函数可返回坐标轴的最小值，也可返回null/undefined来表示“自动计算最小值”（返回null/undefined从v4.8.0开始支持）。
        /// </summary>
        public object? Min { get; set; }

        /// <summary>
        /// 坐标轴刻度最大值。可以设置成特殊值'dataMax'，此时取数据在该轴上的最大值作为最大刻度。不设置时会自动计算最大值保证坐标轴刻度的均匀分布。
        /// 在类目轴中，也可以设置为类目的序数（如类目轴data: ['类A', '类B', '类C']中，序数2表示'类C'。也可以设置为负数，如 -3）。
        /// 当设置成function形式时，可以根据计算得出的数据最大最小值设定坐标轴的最小值。如：max: function (value) { return value.max - 20; }，其中value是一个包含min和max的对象，分别表示数据的最大最小值，这个函数可返回坐标轴的最大值，也可返回null/undefined来表示“自动计算最大值”（返回null/undefined从v4.8.0开始支持）。
        /// </summary>
        public object? Max { get; set; }

        /// <summary>
        /// 只在数值轴中（type: 'value'）有效。是否是脱离0值比例。设置成true后坐标刻度不会强制包含零刻度。在双数值轴的散点图中比较有用。在设置min和max之后该配置项无效。
        /// </summary>
        public bool Scale { get; set; }

        /// <summary>
        /// 坐标轴的分割段数，需要注意的是这个分割段数只是个预估值，最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整。在类目轴中无效。
        /// </summary>
        public int SplitNumber { get; set; }

        /// <summary>
        /// 自动计算的坐标轴最小间隔大小。例如可以设置成1保证坐标轴分割刻度显示成整数。{ minInterval: 1 }只在数值轴或时间轴中（type: 'value'或'time'）有效。
        /// </summary>
        public int MinInterval { get; set; }

        /// <summary>
        /// 自动计算的坐标轴最大间隔大小。例如，在时间轴（（type: 'time'））可以设置成3600 * 24 * 1000保证坐标轴分割刻度最大为一天。{ maxInterval: 3600 * 24 * 1000 }只在数值轴或时间轴中（type: 'value'或'time'）有效。
        /// </summary>
        public int MaxInterval { get; set; }

        /// <summary>
        /// 强制设置坐标轴分割间隔。因为splitNumber是预估的值，实际根据策略计算出来的刻度可能无法达到想要的效果，这时候可以使用interval配合min、max强制设定刻度划分，一般不建议使用。无法在类目轴中使用。在时间轴（type: 'time'）中需要传时间戳，在对数轴（type: 'log'）中需要传指数值。
        /// </summary>
        public object? Interval { get; set; }

        /// <summary>
        /// 对数轴的底数，只在对数轴中（type: 'log'）有效。
        /// </summary>
        public int LogBase { get; set; }

        /// <summary>
        /// 从v5.5.1开始支持，用于指定轴的起始值。
        /// </summary>
        public int StartValue { get; set; }

        /// <summary>
        /// 坐标轴是否是静态无法交互。
        /// </summary>
        public bool Silent { get; set; }

        /// <summary>
        /// 坐标轴的标签是否响应和触发鼠标事件，默认不响应。事件参数如下：
        /// {
        ///     // 组件类型，radiusAxis, angleAxis
        ///     // 对应组件类型都会有一个属性表示组件的index，例如radiusAxis就是radiusAxisIndex
        ///     componentType: string,
        ///     // 未格式化过的刻度值, 点击刻度标签有效
        ///     value: '',
        ///     // 坐标轴名称, 点击坐标轴名称有效
        ///     name: ''
        /// }
        /// </summary>
        public bool TriggerEvent { get; set; }

        /// <summary>
        /// 坐标轴轴线相关设置。
        /// </summary>
        public AxisLine AxisLine { get; set; }

        /// <summary>
        /// 坐标轴刻度相关设置。
        /// </summary>
        public AxisTick AxisTick { get; set; }

        /// <summary>
        /// 从v4.6.0开始支持，坐标轴次刻度线相关设置。注意：次刻度线无法在类目轴（type: 'category'）中使用。示例：1) 函数绘图中使用次刻度线 2) 在对数轴中使用次刻度线。
        /// </summary>
        public MinorTick MinorTick { get; set; }

        /// <summary>
        /// 坐标轴刻度标签的相关设置。
        /// </summary>
        public AxisLabel AxisLabel { get; set; }

        /// <summary>
        /// 坐标轴在grid区域中的分隔线。
        /// </summary>
        public SplitLine SplitLine { get; set; }

        /// <summary>
        /// 从v4.6.0开始支持，坐标轴在grid区域中的次分隔线。次分割线会对齐次刻度线minorTick。
        /// </summary>
        public MinorSplitLine MinorSplitLine { get; set; }

        /// <summary>
        /// 坐标轴在grid区域中的分隔区域，默认不显示。
        /// </summary>
        public SplitArea SplitArea { get; set; }

        /// <summary>
        /// 类目数据，在类目轴（type: 'category'）中有效。
        /// 如果没有设置type，但是设置了axis.data，则认为type是'category'。
        /// 如果设置了type是'category'，但没有设置axis.data，则axis.data的内容会自动从series.data中获取，这会比较方便。不过注意，axis.data指明的是'category'轴的取值范围。如果不指定而是从series.data中获取，那么只能获取到series.data中出现的值。比如说，假如series.data为空时，就什么也获取不到。
        /// 示例：
        /// // 所有类目名称列表
        /// data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
        /// // 每一项也可以是具体的配置项，此时取配置项中的`value`为类目名
        /// data: [{ value: '周一', // 突出周一 textStyle: { fontSize: 20, color: 'red' } }, '周二', '周三', '周四', '周五', '周六', '周日']
        /// </summary>
        public List<AxisData>? Data { get; set; }

        /// <summary>
        /// 坐标轴指示器配置项。
        /// </summary>
        public AxisPointer AxisPointer { get; set; }

        /// <summary>
        /// 从v5.6.0开始支持，坐标轴tooltip设置，注意需设置triggerEvent为true并启用全局option.tooltip组件。
        /// </summary>
        public Tooltip Tooltip { get; set; }

        /// <summary>
        /// 是否开启动画。
        /// </summary>
        public bool Animation { get; set; }

        /// <summary>
        /// 是否开启动画的阈值，当单个系列显示的图形数量大于这个阈值时会关闭动画。
        /// </summary>
        public int AnimationThreshold { get; set; }

        /// <summary>
        /// 初始动画的时长，支持回调函数，可以通过每个数据返回不同的时长实现更戏剧的初始动画效果：animationDuration: function (idx) { // 越往后的数据时长越大 return idx * 100; }。
        /// </summary>
        public object? AnimationDuration { get; set; }

        /// <summary>
        /// 初始动画的缓动效果。不同的缓动效果可以参考缓动示例。
        /// </summary>
        public string? AnimationEasing { get; set; }

        /// <summary>
        /// 初始动画的延迟，支持回调函数，可以通过每个数据返回不同的delay时间实现更戏剧的初始动画效果。如下示例：animationDelay: function (idx) { // 越往后的数据延迟越大 return idx * 100; }，也可以看该示例。
        /// </summary>
        public object? AnimationDelay { get; set; }

        /// <summary>
        /// 数据更新动画的时长。支持回调函数，可以通过每个数据返回不同的时长实现更戏剧的更新动画效果：animationDurationUpdate: function (idx) { // 越往后的数据时长越大 return idx * 100; }。
        /// </summary>
        public object? AnimationDurationUpdate { get; set; }

        /// <summary>
        /// 数据更新动画的缓动效果。
        /// </summary>
        public string? AnimationEasingUpdate { get; set; }

        /// <summary>
        /// 数据更新动画的延迟，支持回调函数，可以通过每个数据返回不同的delay时间实现更戏剧的更新动画效果。如下示例：animationDelayUpdate: function (idx) { // 越往后的数据延迟越大 return idx * 100; }，也可以看该示例。
        /// </summary>
        public object? AnimationDelayUpdate { get; set; }

        /// <summary>
        /// 半径轴所有图形的zlevel值。zlevel用于Canvas分层，不同zlevel值的图形会放置在不同的Canvas中，Canvas分层是一种常见的优化手段。
        /// 我们可以把一些图形变化频繁（例如有动画）的组件设置成一个单独的zlevel。需要注意的是过多的Canvas会引起内存开销的增大，在手机端上需要谨慎使用以防崩溃。
        /// zlevel大的Canvas会放在zlevel小的Canvas的上面。
        /// </summary>
        public int ZLevel { get; set; }

        /// <summary>
        /// 半径轴组件的所有图形的z值。控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。z相比zlevel优先级更低，而且不会创建新的Canvas。
        /// </summary>
        public int Z { get; set; }
    }

    // 以下是之前在转换其他轴类时定义的相关辅助类，在此处同样适用，可根据实际情况放在合适的代码文件结构中

    /// <summary>
    /// 坐标轴名称的截断配置类。
    /// </summary>
    public class NameTruncate
    {
        /// <summary>
        /// 最大宽度，用于限制坐标轴名称显示的最大宽度，超过该宽度将根据ellipsis配置进行截断或处理。
        /// </summary>
        public int MaxWidth { get; set; }

        /// <summary>
        /// 截断时显示的省略号内容，默认为"..."，可自定义为其他字符串。当坐标轴名称超过MaxWidth时，将在截断处显示该省略号。
        /// </summary>
        public string? Ellipsis { get; set; }
    }

    /// <summary>
    /// 坐标轴轴线相关设置类。
    /// </summary>
    public class AxisLine
    {
        /// <summary>
        /// 是否显示轴线。
        /// </summary>
        public bool Show { get; set; }

        /// <summary>
        /// 是否在零刻度上显示轴线，仅对类目轴有效，在type为'category'时有效。
        /// </summary>
        public bool OnZero { get; set; }

        /// <summary>
        /// 当有多个类目轴时，指定在哪个类目轴的零刻度上显示轴线，仅在type为'category'且onZero为true时有效。
        /// </summary>
        public int OnZeroAxisIndex { get; set; }

        /// <summary>
        /// 轴线两端的标记类型，可以是'solid'（实线）、'dashed'（虚线）、'dotted'（点线），也可以是自定义的图片路径（用于在轴线两端显示特定的图形标记）。
        /// </summary>
        public string? Symbol { get; set; }

        /// <summary>
        /// 轴线两端标记的大小，单位px，用于控制轴线两端标记的尺寸。
        /// </summary>
        public int SymbolSize { get; set; }

        /// <summary>
        /// 轴线两端标记的偏移量，第一个值表示水平偏移，第二个值表示垂直偏移，单位px，用于调整轴线两端标记相对于轴线的位置。
        /// </summary>
        public int[]? SymbolOffset { get; set; }

        /// <summary>
        /// 轴线的样式配置。
        /// </summary>
        public LineStyle LineStyle { get; set; }
    }

 
}
